﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using Hadron.License;
using HadronData;

namespace Hadron
{
    class GameStateTitle
        : GameState
    {
        private enum TitleState
        {
            FadeIn,
            Running,
            FadeOut
        }

        private static GameState s_gameState = new GameStateTitle();

        private String[] m_arrayOptions;
        private TitleState m_titleState;
        private float m_fStateTimer;
        private int m_nMenuIndex;
        private bool m_bItemChanged;
        private GameState m_gameStatePending;
        private Texture2D m_textureTitleBackground;
        private Texture2D m_textureGamepadDpad;
        private Texture2D m_textureGamepadStart;
        private GameFont m_gameFont;

        public static GameState Instance
        {
            get { return s_gameState; }
        }

        private GameStateTitle()
        {
            m_arrayOptions = new String[4];
            m_arrayOptions[0] = "Start";
            m_arrayOptions[1] = "Resume";
            m_arrayOptions[2] = "High Scores";
            m_arrayOptions[3] = "Exit";
        }

        public override void OnEnter()
        {
            ContentManager contentManager = m_gameContext.Game.Content;

            m_textureTitleBackground = contentManager.Load<Texture2D>("Graphics\\TitleBackground");
            m_textureGamepadDpad = contentManager.Load<Texture2D>("Graphics\\GamepadDpad");
            m_textureGamepadStart = contentManager.Load<Texture2D>("Graphics\\GamepadStart");
            m_gameFont = new GameFont(AssetManager.Fonts.Title);

            m_titleState = TitleState.FadeIn;
            m_fStateTimer = 0.5f;
            m_nMenuIndex = 0;

            // reset game
            m_gameContext.CurrentLevel = 0;
            m_gameContext.Score = 0;

            // music
            Microsoft.Xna.Framework.Media.MediaPlayer.IsRepeating = true;
            Microsoft.Xna.Framework.Media.MediaPlayer.Play(
                HadronData.AssetManager.Music.Hadron);
        }

        public override void OnExit()
        {
            m_gameFont = null;
            m_textureGamepadStart = null;
            m_textureGamepadDpad = null;
            m_textureTitleBackground = null;
        }

        public override void Update(GameTime p_gameTime)
        {
            float fDeltaTime = (float)p_gameTime.ElapsedGameTime.TotalSeconds;

            if (!m_gameController.Forward && !m_gameController.RotateLeft &&
                !m_gameController.Backward && !m_gameController.RotateRight)
                m_bItemChanged = false;

            if (!m_bItemChanged && (m_gameController.Forward || m_gameController.RotateLeft))
            {
                --m_nMenuIndex;
                if (m_nMenuIndex < 0)
                    m_nMenuIndex = m_arrayOptions.Length - 1;
                m_bItemChanged = true;
                AssetManager.Sounds.MenuItem.Play();
            }

            if (!m_bItemChanged && (m_gameController.Backward || m_gameController.RotateRight))
            {
                m_nMenuIndex = (m_nMenuIndex + 1) % m_arrayOptions.Length;
                m_bItemChanged = true;
                AssetManager.Sounds.MenuItem.Play();
            }

            if (m_titleState == TitleState.Running && m_gameController.Start)
            {
                AssetManager.Sounds.MenuItem.Play();
                switch (m_nMenuIndex)
                {
                    case 0:
                        m_fStateTimer = 0.5f;
                        m_titleState = TitleState.FadeOut;
                        m_gameStatePending = GameStateMission.Instance;

                        // reset play session
                        m_gameContext.Lives = 3;
                        m_gameContext.Score = 0;

                        // reset save game
                        SaveGame saveGame = new SaveGame();
                        saveGame.Save(m_gameContext.StorageDevice);
                        break;
                    case 1:
                        m_fStateTimer = 0.5f;
                        m_titleState = TitleState.FadeOut;
                        m_gameStatePending = GameStateMission.Instance;

                        // restore save game
                        saveGame = new SaveGame();
                        saveGame.Load(m_gameContext.StorageDevice);
                        m_gameContext.CurrentLevel = saveGame.Level;
                        m_gameContext.Score = saveGame.Score;
                        break;
                    case 2:
                        m_fStateTimer = 0.5f;
                        m_titleState = TitleState.FadeOut;
                        m_gameStatePending = GameStateScores.Instance;
                        break;
                    case 3:
                        m_fStateTimer = 0.5f;
                        m_titleState = TitleState.FadeOut;
                        m_gameStatePending = null;
                        break;
                }
            }

            m_fStateTimer = Math.Max(0.0f, m_fStateTimer - fDeltaTime);

            if (m_fStateTimer == 0.0f)
            {
                switch (m_titleState)
                {
                    case TitleState.FadeIn: m_titleState = TitleState.Running; break;
                    case TitleState.FadeOut:
                        if (m_gameStatePending == null)
                            m_gameContext.Game.Exit();
                        else
                            NextState = m_gameStatePending;
                        break;
                }
            }
        }

        public override void Draw(SpriteBatch p_spriteBatch)
        {
            p_spriteBatch.Begin();
            p_spriteBatch.Draw(m_textureTitleBackground, Vector2.Zero, Color.White);

            float fFadeOpacity = 0.0f;
            switch (m_titleState)
            {
                case TitleState.FadeIn: fFadeOpacity = m_fStateTimer * 2.0f; break;
                case TitleState.Running: fFadeOpacity = 0.0f; break;
                case TitleState.FadeOut: fFadeOpacity = 1.0f - m_fStateTimer * 2.0f; break;
            }
            
            // demo indicator
            if (LicenseManager.Instance.LicenseType == LicenseType.Demo)
            {
                m_gameFont.Colour = Color.OrangeRed;
                m_gameFont.DrawString(p_spriteBatch, new Vector2(16.0f, 16.0f), "Demo Version");
            }

            // menu items
            Vector2 vecItemPosition = new Vector2(150.0f, 450.0f);
            for (int nIndex = 0; nIndex < m_arrayOptions.Length; nIndex++)
            {
                m_gameFont.Colour = m_nMenuIndex == nIndex ? Color.YellowGreen : Color.LightGray;
                m_gameFont.DrawString(p_spriteBatch, vecItemPosition, m_arrayOptions[nIndex]);
                vecItemPosition.Y += 16.0f;
            }

            // controls
            m_gameFont.Colour = Color.LightGray;
            p_spriteBatch.Draw(m_textureGamepadDpad, new Vector2(550.0f, 512.0f), Color.White);
            m_gameFont.DrawString(p_spriteBatch, new Vector2(600.0f, 518.0f), "Navigate menu");
            p_spriteBatch.Draw(m_textureGamepadStart, new Vector2(550.0f, 552.0f), Color.White);
            m_gameFont.DrawString(p_spriteBatch, new Vector2(600.0f, 558.0f), "Select option");

            // fade in/out
            p_spriteBatch.Draw(AssetManager.Textures.Fade,
                new Rectangle(0, 0, 800, 600),
                new Color(Color.Black, fFadeOpacity));

            p_spriteBatch.End();
        }
    }
}
